﻿using System;
using System.Collections.Generic;
using System.Text;

namespace MLForgeSharp.Models.SupervisedLearningModels.Linear
{
    /// <summary>
    /// Ridge回归模型
    /// </summary>
    public class RidgeRegModel
    {
        private double[] weights; // 模型权重
        private double alpha; // 正则化强度
        private int maxIterations; // 最大迭代次数
        private double tolerance; // 收敛阈值

        public RidgeRegModel(double alpha = 1.0, int maxIterations = 1000, double tolerance = 1e-4)
        {
            this.alpha = alpha;
            this.maxIterations = maxIterations;
            this.tolerance = tolerance;
        }

        // 训练模型
        public void Train(double[][] data, double[] targets)
        {
            int numSamples = data.Length;
            int numFeatures = data[0].Length;
            weights = new double[numFeatures];

            for (int iter = 0; iter < maxIterations; iter++)
            {
                double[] oldWeights = (double[])weights.Clone();

                for (int j = 0; j < numFeatures; j++)
                {
                    double gradient = 0.0;
                    for (int i = 0; i < numSamples; i++)
                    {
                        double prediction = 0.0;
                        for (int k = 0; k < numFeatures; k++)
                        {
                            if (k != j)
                            {
                                prediction += weights[k] * data[i][k];
                            }
                        }
                        gradient += data[i][j] * (targets[i] - prediction);
                    }
                    gradient /= numSamples;

                    // 添加 L2 正则化项
                    weights[j] = (gradient - alpha * weights[j]) / (1 + alpha);
                }

                double weightDiff = 0.0;
                for (int j = 0; j < numFeatures; j++)
                {
                    weightDiff += Math.Abs(weights[j] - oldWeights[j]);
                }

                if (weightDiff < tolerance)
                {
                    break;
                }
            }
        }

        // 预测
        public double Predict(double[] features)
        {
            double prediction = 0.0;
            for (int i = 0; i < features.Length; i++)
            {
                prediction += weights[i] * features[i];
            }
            return prediction;
        }
    }

    // 示例程序
    public class RidgeRegModelExample
    {
        public RidgeRegModelExample()
        {
            // 示例数据
            double[][] data = new double[][]
        {
            new double[] { 1.0, 2.0 },
            new double[] { 1.1, 2.1 },
            new double[] { 1.2, 2.2 },
            new double[] { 1.3, 2.3 },
            new double[] { 10.0, 10.0 },
            new double[] { 10.1, 10.1 }
        };

            double[] targets = { 0.0, 0.0, 0.0, 0.0, 1.0, 1.0 }; // 目标值

            // 创建模型
            RidgeRegModel model = new RidgeRegModel(alpha: 0.1, maxIterations: 1000, tolerance: 1e-4);

            // 训练模型
            model.Train(data, targets);

            // 预测
            double[] testFeatures = { 1.0, 2.0 };
            double predictedValue = model.Predict(testFeatures);

            System.Console.WriteLine("预测值: " + predictedValue);
        }
    }
}
